package org.example.trace;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import org.example.App;
import org.example.appstart.StartAppInfo;
import org.example.constant.Resource;
import org.example.utlis.CmdUtils;
import org.example.utlis.FXUtils;
import org.example.utlis.JsonUtils;

import java.util.*;

import static org.apache.commons.io.IOUtils.close;

public class TraceElementManagerController {
    @FXML
    private CheckBox adb, audio, am, aidl, binder_driver;
    @FXML
    private CheckBox binder_lock, bionic, camera, dalvik, database;
    @FXML
    private CheckBox disk, freq, gfx, hal, i2c;
    @FXML
    private CheckBox idle, input, ion, irq, memory;
    @FXML
    private CheckBox memreclaim, network, nnapi, pagecache, pdx;
    @FXML
    private CheckBox pm, power, regulators, res, rro;
    @FXML
    private CheckBox rs, sched, sm, ss, sync;
    @FXML
    private CheckBox thermal, thermal_tj, vibrator, video, view;
    @FXML
    private CheckBox webview, wm, workq;

    @FXML
    private TableView<TagGroupEntity> tableView;
    private List<TagGroupEntity> tagGroupList = new ArrayList<>();

    private HashMap<String, CheckBox> tagMap;

    private String selectedTags;
    private Stage mStage;
    private JsonUtils<TagGroupEntity> mJsonUtils;
    private ChooseOverListener mChooseOverListener;
    public interface ChooseOverListener {
        void onOver(String selectedTags);
    }

    public TraceElementManagerController() {
    }

    public void setChooseOverListener(ChooseOverListener chooseOverListener) {
        mChooseOverListener = chooseOverListener;
    }

    public void setStage(Stage stage) {
        mStage = stage;
    }

    public void initialize() {
        initMap();
        initTable();
    }

    private void updateUI(String[] traceTagPre) {
        if (traceTagPre == null) return;
        for (String text : traceTagPre) {
            if (tagMap.get(text) == null) break;
            tagMap.get(text).setSelected(true);
        }
    }

    /**
     * 从checkbox获取选中的tag，并追加到selectedTags
     */
    private void checkSelect() {
        StringBuilder traceTag = new StringBuilder();
        tagMap.forEach((text,cb) -> {
            if(cb.isSelected()){
                traceTag.append(text).append(Resource.SPLIT_EMPTY);
            }
        });
        selectedTags = traceTag.toString();
    }

    public void onCancel(MouseEvent mouseEvent) {
        FXUtils.initSimpleDialog("退出", "是否保存修改？", () ->{
            onSelectedOver();
        }, this::close);
    }

    private void close() {
        Platform.runLater(() -> mStage.close());
    }


    public void onSelectedOver() {
        onSelectedOver(true);
    }

    /**
     * 发送tags并关闭页面
     */
    public void onSelectedOver(boolean isReadSelect) {
        if (isReadSelect) checkSelect();
        if (mChooseOverListener != null ) mChooseOverListener.onOver(selectedTags);
        close();
    }

    private final String path = "../../config/tag-group.json";

    /**
     * 将勾选的tag保存到常用
     */
    public void onSave() {
        //先弹窗确认别名
        TextInputDialog dialog = new TextInputDialog();
        dialog.setTitle("将勾选保存到常用");
        dialog.setHeaderText("请输入该tag组别名");
        dialog.setContentText("别名:");
        App.useJMetro(dialog.getDialogPane().getScene());

        Optional<String> result = dialog.showAndWait();
        if (result.isPresent()){
            //1.获取别名
            final String alias = result.get();
            //2.获取tag组
            checkSelect();
            //3.生成对象
            final TagGroupEntity entity = new TagGroupEntity(alias, selectedTags);
            //4.保存
            tagGroupList.add(entity);
            mJsonUtils.writeFile(tagGroupList);
            //5.UI
            tableView.setItems(FXCollections.observableArrayList(tagGroupList));
        }
    }

    @FXML
    void onDelete() {
        FXUtils.initSimpleDialog("删除选中", "确认要删除吗？", () -> {
            ObservableList<TagGroupEntity> selectedItems = tableView.getSelectionModel().getSelectedItems();
            tagGroupList.removeAll(selectedItems);
            tableView.setItems(FXCollections.observableArrayList(tagGroupList));
            mJsonUtils.writeFile(tagGroupList);
        }, null);
    }

    private void initTable() {
        mJsonUtils = new JsonUtils<>(path, TagGroupEntity.class);

        tableView.setPlaceholder(new Label("空白"));
        tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        ObservableList<? extends TableColumn<?, ?>> columns = tableView.getColumns();
        columns.get(0).setCellValueFactory(new PropertyValueFactory<>("alias"));
        columns.get(1).setCellValueFactory(new PropertyValueFactory<>("tags"));

        tagGroupList = mJsonUtils.readFile();
        if (tagGroupList == null || tagGroupList.size() == 0) {
            tagGroupList.add(new TagGroupEntity("常用1", Resource.TRACE_TAG_NORMAL_1));
            tagGroupList.add(new TagGroupEntity("常用1+pagecache+thermal", Resource.TRACE_TAG_NORMAL_2));
            mJsonUtils.writeFile(tagGroupList);
        }

        //双击选中
        tableView.setRowFactory(tv -> {
            TableRow<TagGroupEntity> row = new TableRow<>();
            row.setOnMouseClicked(event -> {
                if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
                    TagGroupEntity rowData = row.getItem();
                    selectedTags = rowData.getTags();
                    onSelectedOver(false);
                }
            });
            return row ;
        });

        ObservableList<TagGroupEntity> list = FXCollections.observableArrayList(tagGroupList);
        tableView.setItems(list);
    }

    private void initMap() {
        tagMap = new LinkedHashMap<>();

        tagMap.put("adb", adb);
        tagMap.put("audio", audio);
        tagMap.put("am", am);
        tagMap.put("aidl", aidl);
        tagMap.put("binder_driver", binder_driver);

        tagMap.put("binder_lock", binder_lock);
        tagMap.put("bionic", bionic);
        tagMap.put("camera", camera);
        tagMap.put("dalvik", dalvik);
        tagMap.put("database", database);

        tagMap.put("disk", disk);
        tagMap.put("freq", freq);
        tagMap.put("gfx", gfx);
        tagMap.put("hal", hal);
        tagMap.put("i2c", i2c);

        tagMap.put("idle", idle);
        tagMap.put("input", input);
        tagMap.put("ion", ion);
        tagMap.put("irq", irq);
        tagMap.put("memory", memory);

        tagMap.put("memreclaim", memreclaim);
        tagMap.put("network", network);
        tagMap.put("nnapi", nnapi);
        tagMap.put("pagecache", pagecache);
        tagMap.put("pdx", pdx);

        tagMap.put("pm", pm);
        tagMap.put("power", power);
        tagMap.put("regulators", regulators);
        tagMap.put("res", res);
        tagMap.put("rro", rro);

        tagMap.put("rs", rs);
        tagMap.put("sched", sched);
        tagMap.put("sm", sm);
        tagMap.put("ss", ss);
        tagMap.put("sync", sync);

        tagMap.put("thermal", thermal);
        tagMap.put("thermal_tj", thermal_tj);
        tagMap.put("vibrator", vibrator);
        tagMap.put("video", video);
        tagMap.put("view", view);

        tagMap.put("webview", webview);
        tagMap.put("wm", wm);
        tagMap.put("workq", workq);

        tagMap.forEach((text, cb) -> cb.setText(text));
    }
}
